package com.whvronk.server.operation;

import com.whvronk.server.util.JsonUtils;
import io.netty.buffer.ByteBuf;
import lombok.Data;

import java.nio.charset.StandardCharsets;

@Data
public abstract class Message<T extends MessageBody> {

    private MessageHeader messageHeader;
    private T messageBody;

    public void encode(ByteBuf byteBuf) throws Exception {
        byteBuf.writeShort(messageHeader.getVersion());
        byteBuf.writeShort(messageHeader.getOp());
        byteBuf.writeInt((int) messageHeader.getId());
        byteBuf.writeShort(messageHeader.getType());
        byteBuf.writeShort(messageHeader.getReserved());
        String json = JsonUtils.objectToJson(messageBody);
        if (json == null) {
            throw new Exception();
        }
        byteBuf.writeBytes(json.getBytes());
    }

    public abstract Class<T>getMessageBodyDecodeClass(int op,int type);

    public void decode(ByteBuf msg, String ip) throws Exception {
        //使用readUnsignedShort()方法是为了读取没有符号的短整型的值,为了避免出现负数的情况,占2个字节
        int version = msg.readUnsignedShort();
        int op = msg.readUnsignedShort();
        int type = msg.readUnsignedShort();
        int reserved = msg.readUnsignedShort();
        long id = msg.readUnsignedInt(); //读取无符号的整型的值,避免出现负数的情况,占4个字节
        this.messageHeader = new MessageHeader(version, op, type, reserved, id); //messageHeader一共占12个字节

        Class<T> bodyClazz = getMessageBodyDecodeClass(op, type);
            if (bodyClazz == null) {
                throw new Exception();
            }
            T body = JsonUtils.jsonToPojo(msg.toString(StandardCharsets.UTF_8), bodyClazz);
            if (body == null) {
                throw new Exception();
            }
            this.messageBody = body;
    }
}
